package com.fingard.dsp.bank.directbank.zjtlcb02;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import java.io.File;
import java.sql.Connection;
import java.util.*;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.db.JDBCHelper;
import com.fingard.dsp.bank.directbank.bankInterface.IReceipt;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.AESCipher;
import com.fingard.dsp.bank.directbank.zjtlcb02.util.MD5Util;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.ReqQryReceipt;
import com.fingard.dsp.bank.reqrespobj.downloadreceipt.RetAtsReceipt;
import com.fingard.io.FileHelper;
import com.fingard.text.StringHelper;

/**
 * Created by F on 2019/1/2.
 */
public class ZJTLCB02Receipt extends ZJTLCB02Base implements IReceipt {

    //交易传入的数据
    private String receiptSaveToMainDir = "";

    private static final String SELECTRECEIPT = "SELECT RECEIPTFILE FROM RECEIPTMAPPING WHERE BANK=? AND OWNACT=? AND BUSDATE=? AND RECEIPTNO=?;";

    /**
     * 电子回单查询
     */
    @Override
    public RetAtsReceipt qryReceipt(ReqQryReceipt p_reqReceipt) throws Exception {
        //余额查询返回ATS的对象
        RetAtsReceipt retAts = new RetAtsReceipt(p_reqReceipt.reqHeader);
        receiptSaveToMainDir = FGBiz.dspCenter.dspSet.receiptMainDir;
        if (!StringHelper.isNullOrEmpty(receiptSaveToMainDir)) {
            if (!StringHelper.isNullOrEmpty(FGBiz.dspCenter.dspSet.receiptShareDir)) {
                if (!StringHelper.isNullOrEmpty(FGBiz.dspCenter.dspSet.receiptPushServerUrl)) {
                    download(p_reqReceipt);
                    retAts.respCode = "0";
                    retAts.respInfo = "后台处理中";
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "DSPSystem未配置回单文件推送地址";
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "DSPSystem未配置回单文件共享目录";
            }
        } else {
            retAts.respCode = "-1";
            retAts.respInfo = "DSPSystem未配置回单文件下载保存主目录";
        }
        retAts.writeRetToATS();
        return retAts;
    }

    public void download(ReqQryReceipt p_reqReceipt) throws Exception{
        RetAtsReceipt retAts = new RetAtsReceipt(p_reqReceipt.reqHeader);
        Connection conn = null;
        try{
            conn = FGBiz.getLocalDbConn();
            Calendar tmpCalendarFrom = Calendar.getInstance();
            tmpCalendarFrom.setTime(p_reqReceipt.getDateFrom());
            Calendar tmpCalendarTo = Calendar.getInstance();
            tmpCalendarTo.setTime(p_reqReceipt.getDateTo());
            int tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));
            int tmpIntTo = Integer.parseInt(Format.Date8Format.format(tmpCalendarTo.getTime()));
            while (tmpIntFrom <= tmpIntTo) {
                Date fromDateStep = tmpCalendarFrom.getTime();
                tmpCalendarFrom.add(Calendar.DAY_OF_MONTH, 1);
                tmpIntFrom = Integer.parseInt(Format.Date8Format.format(tmpCalendarFrom.getTime()));

                //1.查询全部回单
                int tmpNowReadStart = 1;//起始笔数
                int tmpNowReadNum = 0;//已查询笔数
                List<String> receiptNoList=new ArrayList<String>();//记录回单编号
                Map<String,Integer> tmpTotalNum = new HashMap<String, Integer>();//记录总数
                while (tmpNowReadNum==0 || tmpNowReadNum<tmpTotalNum.get("totalCount")){
                    String seqNo=getQryTransID();
                    //报文头
                    JSONObject jsonHead = new JSONObject();
                    jsonHead.put("txSno",p_reqReceipt.reqHeader.transSeqID);// 交易流水号
                    jsonHead.put("mrchSno",p_reqReceipt.reqHeader.reqSeqID);// 商户业务编号
                    jsonHead.put("bussSeqNo",seqNo);// 银行业务编号
                    jsonHead.put("txTime", Format.DateTimeFormat.format(new Date()));// 交易时间
                    jsonHead.put("productId",""); // 产品ID
                    //报文体
                    JSONObject jsonBody = new JSONObject();
                    jsonBody.put("acctNo",p_reqReceipt.actNum);//账号
                    jsonBody.put("acctType","1");//账户类型 1：活期；2：定期；
                    jsonBody.put("startDate",Format.Date8Format.format(fromDateStep));//开始日期
                    jsonBody.put("endDate",Format.Date8Format.format(fromDateStep));//终止日期
                    jsonBody.put("strtAmt","");//开始金额
                    jsonBody.put("endAmt","");//结束金额
                    jsonBody.put("againPrintFlg","");//补打标志
                    jsonBody.put("currentNum",tmpNowReadStart);//当前记录号
                    jsonBody.put("totalNum",getBankConfig().getValueAsString("pageSize"));//本页记录总数
                    jsonBody.put("queryPrintFlag","0");//查询打印标志 0（查询）、1（生成zip文件）
                    jsonBody.put("prtMd","");//打印方式 查询不传。单笔部分，批量全部
                    jsonBody.put("othrAcctNo","");//对方账号
                    jsonBody.put("ccy",convertCurToBank(p_reqReceipt.actCur));//币种
                    jsonBody.put("drCrFlag","");//借贷标志
                    jsonBody.put("productType","1");//产品类别 1历史回单
                    jsonBody.put("seqMd","0");//排序方式 0-asc 1-desc
                    String data="<?xml version=\"1.0\" encoding=\"utf-8\"?><T><D><M><k>帐号</k><v>"+p_reqReceipt.actNum+"</v></M></D><E><M><k>客户号</k><v>"+bankFront.org+"</v></M></E></T>";
                    jsonBody.put("signCert",ukeyData(data).trim());//签名数据
                    //jsonBody.put("signCert","111");//签名数据
                    jsonBody.put("clientNo",bankFront.org);//	客户号
                    jsonBody.put("rcptSmyArray","");//	回单编号数组
                    //报文内容
                    JSONObject jsonReqData = new JSONObject();
                    jsonReqData.put("head", jsonHead);
                    jsonReqData.put("body", jsonBody);
                    //拼接请求json串:data
                    JSONObject jsonObject = new JSONObject();
                    ZJTLCB02Header tlcb02Header = new ZJTLCB02Header();
                    tlcb02Header.seqNO = seqNo;
                    //验证开发者
                    String appAccessToken=checkDeveloper(seqNo);
                    tlcb02Header.appAccessToken = appAccessToken;
                    //MD5加密签名串
                    WriteBankLogLn("MD5加密原文:"+new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                    String sign= MD5Util.md5_(new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                    tlcb02Header.sign = sign;
                    JsonHeader(jsonObject, tlcb02Header);
                    jsonObject.put("reqData", jsonReqData);
                    WriteBankLogLn("发送银行请求报文原文："+jsonObject.toString());
                    //AES256加密
                    String aesData= AESCipher.encrypt(jsonReqData.toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                    jsonObject.put("reqData", aesData);
                    //发送请求报文
                    String[] bankResult = sendToBank(jsonObject.toString(),"receiptQryBCDCAndPrint");
                    //处理响应报文
                    if (bankResult[0].length() == 0) {
                        JSONObject jsonArray = JSONObject.fromObject(bankResult[1].replaceAll(" ",""));
                        //AES256解密
                        String rspData = AESCipher.decrypt(jsonArray.get("rspData").toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                        jsonArray.put("rspData",rspData);
                        WriteBankLogLn("银行返回已解密的报文："+jsonArray.toString());
                        if(!"".equals(jsonArray.get("errorCode")) && jsonArray.get("errorCode")!=null){
                            if(isActiveRetCode(jsonArray.get("errorCode").toString())){
                                JSONObject jsonRspData=JSONObject.fromObject(rspData);
                                JSONObject jsonBodys=(JSONObject)jsonRspData.get("body");
                                //开始处理报文体
                                if(!"".equals(jsonBodys) && jsonBodys!=null){
                                    String recordCount = jsonBodys.get("totalNum").toString().trim();//获取页面记录条数
                                    String totalCount = jsonBodys.get("totalRows").toString().trim();//获取总记录数
                                    if(tmpTotalNum.containsKey("totalCount")){
                                        if(tmpTotalNum.get("totalCount").intValue()!=Integer.valueOf(totalCount).intValue()){
                                            retAts.respCode ="-1";
                                            retAts.respInfo = "相同条件前后查出来的总数不一致";
                                            break;
                                        }
                                    }else{
                                        if("0".equals(totalCount)){
                                            retAts.respCode ="0";
                                            retAts.respInfo = "该时间段的总明细条数为0";
                                            break;
                                        }
                                        tmpTotalNum.put("totalCount",Integer.valueOf(totalCount));//记录总条数
                                    }
                                    int readCount =0;
                                    String rcptSmyArray=jsonBodys.get("rcptSmyArray").toString();
                                    JSONArray json = JSONArray.fromObject(rcptSmyArray);
                                    if(json.size()>0){
                                        for(int i=0;i<json.size();i++){
                                            JSONObject object = json.getJSONObject(i);
                                            String receiptId=object.get("rcptNo").toString();
                                            String acctNo=object.get("acctNo").toString();
                                            String ccy=convertCurToATS(object.get("ccy").toString());
                                            String oriTranDate=object.get("oriTranDate").toString();
                                            if(StringHelper.hasAnyChar(receiptId) && StringHelper.hasAnyChar(acctNo)
                                                    && StringHelper.hasAnyChar(ccy) && StringHelper.hasAnyChar(oriTranDate)){
                                                receiptNoList.add(new StringBuilder(receiptId).append("|").append(acctNo).append("|").append(ccy).append("|").append(oriTranDate).toString());
                                                readCount++;
                                            }
                                        }
                                        //查询记录数和遍历数不一致
                                        if(readCount!=Integer.valueOf(recordCount)){
                                            retAts.respCode = "-1";
                                            retAts.respInfo = "统计有误，回单编号存在为空，或者返回总数与实际循环数不一致";
                                            break;
                                        }
                                        tmpNowReadStart +=readCount;
                                        tmpNowReadNum +=readCount;
                                    }else {
                                        retAts.respCode ="-1";
                                        retAts.respInfo = "统计有误";
                                        break;
                                    }
                                }else {
                                    retAts.respCode ="0";
                                    retAts.respInfo = "该时间段的总条数为0";
                                    break;
                                }
                            }else {
                                retAts.respCode = "-1";
                                retAts.respInfo = jsonArray.get("errorMsg").toString();
                                break;
                            }
                        }else {
                            retAts.respCode = "-1";
                            retAts.respInfo = "响应码未返回";
                            break;
                        }
                    }else {
                        retAts.respCode = "-1";
                        retAts.respInfo = bankResult[1];
                        break;
                    }
                }
                WriteBankLogLn("已查询到"+Format.Date8Format.format(fromDateStep)+"回单数为："+tmpNowReadNum);
                //2.开始循环下载回单
                if(receiptNoList.size()>0){
                    for (String contentString:receiptNoList){
                        String[] content=contentString.split("\\|");
                        if(content.length==4){
                            //=====防重操作1.1已查询文件已上传共享目录=====
                            Map<String, Object>  tabMap = JDBCHelper.execQuerySingle(conn, SELECTRECEIPT, new Object[]{reqHeader.bankCode, content[1], Integer.parseInt(content[3].replace("-", "")), content[0]});
                            if (tabMap != null && tabMap.size() > 0 && tabMap.containsKey("RECEIPTFILE")) {
                                WriteBankLogLn("回单编号"+content[0]+"已下载成功/上传成功，请勿重复查询");
                                continue;
                            }
                            //=====防重操作1.2已查询文件但文件未上传到共享目录=====
                            String reqNoFile2=FGBiz.dspCenter.dspSet.dataDirPath + File.separator + "datafile" + File.separator + bankFront.code
                                    + File.separator + "cltRefNoFile";
                            if(!FileHelper.existFile(reqNoFile2)){
                                FileHelper.mkdir(reqNoFile2);
                            }
                            File file2=new File(reqNoFile2);
                            if(file2.listFiles().length>0){
                                boolean flag=false;
                                for (File files:file2.listFiles()){
                                    if(files.getName().contains(content[0].trim())){
                                        WriteBankLogLn("此回单"+content[0].trim()+"已查询，请勿重复查询。如需重新查询，请删除文件："+files.getPath());
                                        flag=true;
                                        continue;
                                    }
                                }
                                if(flag){
                                    continue;
                                }
                            }
                            //拼接请求报文
                            String seqNo=getQryTransID();
                            //报文头
                            JSONObject jsonHead = new JSONObject();
                            jsonHead.put("txSno",p_reqReceipt.reqHeader.transSeqID);// 交易流水号
                            jsonHead.put("mrchSno",p_reqReceipt.reqHeader.reqSeqID);// 商户业务编号
                            jsonHead.put("bussSeqNo",seqNo);// 银行业务编号
                            jsonHead.put("txTime", Format.DateTimeFormat.format(new Date()));// 交易时间
                            jsonHead.put("productId",""); // 产品ID
                            //报文体
                            JSONObject jsonBody = new JSONObject();
                            jsonBody.put("acctNo",p_reqReceipt.actNum);//账号
                            jsonBody.put("acctType","1");//账户类型 1：活期；2：定期；
                            jsonBody.put("startDate",Format.Date8Format.format(fromDateStep));//开始日期
                            jsonBody.put("endDate",Format.Date8Format.format(fromDateStep));//终止日期
                            jsonBody.put("strtAmt","");//开始金额
                            jsonBody.put("endAmt","");//结束金额
                            jsonBody.put("againPrintFlg","");//补打标志
                            jsonBody.put("currentNum","1");//当前记录号
                            jsonBody.put("totalNum",getBankConfig().getValueAsString("pageSize"));//本页记录总数
                            jsonBody.put("queryPrintFlag","1");//查询打印标志 0（查询）、1（生成zip文件）
                            jsonBody.put("prtMd","1");//打印方式 查询不传。单笔部分1，批量全部0
                            jsonBody.put("othrAcctNo","");//对方账号
                            jsonBody.put("ccy",convertCurToBank(p_reqReceipt.actCur));//币种
                            jsonBody.put("drCrFlag","");//借贷标志
                            jsonBody.put("productType","1");//产品类别 1历史回单
                            jsonBody.put("seqMd","0");//排序方式 0-asc 1-desc
                            String data="<?xml version=\"1.0\" encoding=\"utf-8\"?><T><D><M><k>账号</k><v>"+p_reqReceipt.actNum+"</v></M></D><E><M><k>客户号</k><v>"+bankFront.org+"</v></M></E></T>";
                            //jsonBody.put("signCert","111");
                            jsonBody.put("signCert",ukeyData(data).trim());//签名数据
                            jsonBody.put("clientNo",bankFront.org);//	客户号
                            JSONArray array=new JSONArray();
                            JSONObject object=new JSONObject();
                            object.put("rcptNo",content[0]);
                            array.add(object);
                            jsonBody.put("rcptSmyArray",array);//	回单编号数组
                            //报文内容
                            JSONObject jsonReqData = new JSONObject();
                            jsonReqData.put("head", jsonHead);
                            jsonReqData.put("body", jsonBody);
                            //拼接请求json串:data
                            JSONObject jsonObject = new JSONObject();
                            ZJTLCB02Header tlcb02Header = new ZJTLCB02Header();
                            tlcb02Header.seqNO = seqNo;
                            //验证开发者
                            String appAccessToken=checkDeveloper(seqNo);
                            tlcb02Header.appAccessToken = appAccessToken;
                            //MD5加密签名串
                            WriteBankLogLn("MD5加密原文:"+new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                            String sign= MD5Util.md5_(new StringBuilder(jsonReqData.toString()).append(seqNo).append(bankFront.keyID).toString());
                            tlcb02Header.sign = sign;
                            JsonHeader(jsonObject, tlcb02Header);
                            jsonObject.put("reqData", jsonReqData);
                            WriteBankLogLn("发送银行请求报文原文："+jsonObject.toString());
                            //AES256加密
                            String aesData= AESCipher.encrypt(jsonReqData.toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                            jsonObject.put("reqData", aesData);
                            //发送请求报文
                            String[] bankResult = sendToBank(jsonObject.toString(),"receiptQryBCDCAndPrint");
                            if (bankResult[0].length() == 0) {
                                JSONObject jsonArray = JSONObject.fromObject(bankResult[1].replaceAll(" ", ""));
                                //AES256解密
                                String rspData = AESCipher.decrypt(jsonArray.get("rspData").toString(), MD5Util.md5_(seqNo + appAccessToken + bankFront.keyID));
                                jsonArray.put("rspData", rspData);
                                WriteBankLogLn("银行返回已解密的报文：" + jsonArray.toString());
                                if (!"".equals(jsonArray.get("errorCode")) && jsonArray.get("errorCode") != null) {
                                    if (isActiveRetCode(jsonArray.get("errorCode").toString())) {
                                        JSONObject jsonRspData = JSONObject.fromObject(rspData);
                                        JSONObject jsonBodys = (JSONObject) jsonRspData.get("body");
                                        //开始处理报文体
                                        if (!"".equals(jsonBodys) && jsonBodys != null) {
                                            if(jsonBodys.get("filePath")!=null){
                                                //拼接已成功请求的回单信息
                                                String filePath=jsonBodys.get("filePath").toString();
                                                JSONArray json = JSONArray.fromObject(jsonBodys.get("rcptSmyArray").toString());
                                                if(json.size()==1){
                                                    String receiptId=json.getJSONObject(0).get("rcptNo").toString();
                                                    if(content[0].equalsIgnoreCase(receiptId)){
                                                        //记录已请求成功的回单信息
                                                        //回单编号|文件路径|帐号|币种|交易日期|
                                                        generateReceiptCodeFile(content[0], filePath, content[1], content[2],content[3]);
                                                    }
                                                }
                                            }else {
                                                retAts.respCode ="-1";
                                                retAts.respInfo = "回单"+content[0]+"返回文件路径为空";
                                                break;
                                            }
                                        }else {
                                            retAts.respCode ="-1";
                                            retAts.respInfo = "返回打印回单数据为空";
                                            break;
                                        }
                                    }else {
                                        retAts.respCode = "-1";
                                        retAts.respInfo = jsonArray.get("errorMsg").toString();
                                        break;
                                    }
                                }else {
                                    retAts.respCode = "-1";
                                    retAts.respInfo = "响应码未返回";
                                    break;
                                }
                            }else {
                                retAts.respCode = "-1";
                                retAts.respInfo = bankResult[1];
                                break;
                            }
                        }else {
                            WriteBankLogLn("返回数据缺失："+contentString);
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = e.getMessage();
            WriteBankLogLn("泰隆银行打印回单："+e);
        }finally {
            conn.close();
        }
    }
}
